package com.kaluli.project.utils;

import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

import org.apache.log4j.Logger;
import org.hibernate.engine.transaction.jta.platform.internal.SynchronizationRegistryBasedSynchronizationStrategy;

import com.mysql.fabric.xmlrpc.base.Data;

/**
 * 日期工具类
 * 
 * @file DateUtil.java
 * @package com.aodun.famous.tools
 * @project project_famous_server
 * @version 1.0
 * @createTime Apr 18, 2011 10:03:55 PM
 * @author zhouhan
 */
public class DateUtil {
	/**
	 * 注释内容
	 */
	private static final Logger log = Logger.getLogger(DateUtil.class);

	/**
	 * 默认日期格式
	 */
	public static final String DEFAULT_FORMAT = "yyyy-MM-dd HH:mm:ss";

	public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";

	public static final String[] WEEK_DAYS = { "日", "一", "二", "三", "四", "五", "六" };

	/**
	 * <默认构造函数>
	 */
	private DateUtil() {
	}
	
	public static String getCurrentDate(){
		SimpleDateFormat sdf = new SimpleDateFormat(DEFAULT_FORMAT);
		return sdf.format(new Date());
	}
	
	public static String getCurrentDay(){
		SimpleDateFormat sdf = new SimpleDateFormat(DEFAULT_DATE_FORMAT);
		return sdf.format(new Date());
	}

	/**
	 * <字符串转换成日期> <如果转换格式为空，则利用默认格式进行转换操作>
	 * 
	 * @param str
	 *            字符串
	 * @param format
	 *            日期格式
	 * @return 日期
	 * @see [类、类#方法、类#成员]
	 */
	public static Date str2Date(String str, String format) {
		if (null == str || "".equals(str)) {
			return null;
		}
		// 如果没有指定字符串转换的格式，则用默认格式进行转换
		if (null == format || "".equals(format)) {
			format = DEFAULT_FORMAT;
		}
		SimpleDateFormat sdf = new SimpleDateFormat(format);
		Date date = null;
		try {
			date = sdf.parse(str);
			return date;
		} catch (ParseException e) {

		}

		return null;
	}

	/**
	 * <一句话功能简述> <功能详细描述>
	 * 
	 * @param date
	 *            日期
	 * @param format
	 *            日期格式
	 * @return 字符串
	 * @see [类、类#方法、类#成员]
	 */
	public static String date2Str(Date date, String format) {
		if (null == date) {
			return null;
		}
		SimpleDateFormat sdf = new SimpleDateFormat(format);
		return sdf.format(date);
	}

	/**
	 * <时间戳转换为字符串> <功能详细描述>
	 * 
	 * @param time
	 * @return
	 * @see [类、类#方法、类#成员]
	 */
	public static String timestamp2Str(Timestamp time) {
		Date date = new Date(time.getTime());
		return date2Str(date, DEFAULT_FORMAT);
	}

	public static String timestamp2Str(Timestamp time, String format) {
		Date date = new Date(time.getTime());
		return date2Str(date, format);
	}

	/**
	 * <一句话功能简述> <功能详细描述>
	 * 
	 * @param str
	 * @return
	 * @see [类、类#方法、类#成员]
	 */
	public static Timestamp str2Timestamp(String str) {
		Date date = str2Date(str, DEFAULT_FORMAT);
		return new Timestamp(date.getTime());
	}

	/**
	 * 
	 * @return 获得当前系统时间
	 */
	public static Timestamp getCutTime() {
		return new Timestamp(System.currentTimeMillis());
	}

	/**
	 * 
	 * @return 获得当前系统时间
	 */
	public static Date getCutTimeForDate() {
		return new Date(System.currentTimeMillis());
	}

	/**
	 * 
	 * @return 获取当前日期 8位字符串
	 */
	public static String getCutDateStr() {
		Date date = new Date(System.currentTimeMillis());
		return date2Str(date, "yyyyMMdd");
	}

	/**
	 * 
	 * @param date1
	 * @param date2
	 * @return 返回两个日期间的相隔天数
	 */
	public static int intervalDays(Date date1, Date date2) {
		Calendar fromCalendar = Calendar.getInstance();
		fromCalendar.setTime(date1);
		fromCalendar.set(Calendar.HOUR_OF_DAY, 0);
		fromCalendar.set(Calendar.MINUTE, 0);
		fromCalendar.set(Calendar.SECOND, 0);
		fromCalendar.set(Calendar.MILLISECOND, 0);

		Calendar toCalendar = Calendar.getInstance();
		toCalendar.setTime(date2);
		toCalendar.set(Calendar.HOUR_OF_DAY, 0);
		toCalendar.set(Calendar.MINUTE, 0);
		toCalendar.set(Calendar.SECOND, 0);
		toCalendar.set(Calendar.MILLISECOND, 0);
		int days = (int) ((toCalendar.getTime().getTime() - fromCalendar.getTime().getTime()) / (1000 * 60 * 60 * 24));
		return Math.abs(days);
	}

	
	/**
	 * 计算开始时间,结束时间中间的小时差
	 * @param startTime
	 * @param endTime
	 * @return
	 */
	public static int intervalHours(Date startTime, Date endTime){
		Calendar toCalendar = Calendar.getInstance();
		toCalendar.setTime(endTime);
		Calendar fromCalendar = Calendar.getInstance();
		fromCalendar.setTime(startTime);
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
		int minusDays = 0;
		while (true) {
		  minusDays++;
		  // Day increasing by 1
		  fromCalendar.add(Calendar.DAY_OF_MONTH, 1);
		  
		  if (df.format(fromCalendar.getTime()).
		            equals(df.format(toCalendar.getTime()))) {
		    break;
		  }
		  if(minusDays>10000){
			  System.out.println(df.format(fromCalendar.getTime())+">>>>>>"+df.format(startTime));
			  break;
		  }
		}
//		System.out.println("The subtraction between two time is " + (minusDays + 1));
		return minusDays;
	}
	
	public static int intervalHourTest(Date startTime, Date endTime) {
		SimpleDateFormat df = new SimpleDateFormat(DEFAULT_FORMAT);
		String startStr = df.format(startTime);
		String endStr = df.format(endTime);
		String[] start = startStr.split(" ");
		String[] startDay = start[0].split("-");
		String[] startSecond = start[1].split(":");

		String[] end = endStr.split(" ");
		String[] endDay = end[0].split("-");
		String[] endSecond = end[1].split(":");
		Calendar fromCalendar = Calendar.getInstance();
		
		fromCalendar.setTime(endTime);
		fromCalendar.set(Calendar.HOUR_OF_DAY, Integer.valueOf(endSecond[0]));
		fromCalendar.set(Calendar.MINUTE, 0);
		fromCalendar.set(Calendar.SECOND, 0);
		fromCalendar.set(Calendar.MILLISECOND, 0);
		

		Calendar toCalendar = Calendar.getInstance();
		toCalendar.setTime(startTime);
		toCalendar.set(Calendar.HOUR_OF_DAY, Integer.valueOf(startSecond[0]));
		toCalendar.set(Calendar.MINUTE, 0);
		toCalendar.set(Calendar.SECOND, 0);
		toCalendar.set(Calendar.MILLISECOND, 0);
		int hour = (int) ((toCalendar.getTime().getTime() - fromCalendar.getTime().getTime()) / (1000 * 60 * 60));
		return Math.abs(hour);
	}


	/**
	 * 
	 * @param basicDate
	 * @param n
	 * @return 给定一个日期，返回加减n天后的日期 (n为负时，返回n天前的日期)
	 */
	public static Date nDaysAfterOneDate(Date basicDate, int n) {
		/*
		 * long nDay = (basicDate.getTime() / (24 * 60 * 60 * 1000) + 1 + n) *
		 * (24 * 60 * 60 * 1000); basicDate.setTime(nDay); return basicDate;
		 */
		// 上面的方法会改表输入的日期值
		long nDay = (basicDate.getTime() / (24 * 60 * 60 * 1000) + 1 + n) * (24 * 60 * 60 * 1000);
		Date date = new Date();
		date.setTime(nDay);
		return date;
	}

	/**
	 * 
	 * @param basicDate
	 * @param n
	 * @return 给定一个日期，返回加减n天后的日期 (8位) (n为负时，返回n天前的日期)
	 */
	public static String nDaysAfterOneDateStr(Date basicDate, int n) {
		/*
		 * long nDay = (basicDate.getTime() / (24 * 60 * 60 * 1000) + 1 + n) *
		 * (24 * 60 * 60 * 1000); basicDate.setTime(nDay); return
		 * date2Str(basicDate, DEFAULT_DATE_FORMAT);
		 */
		// 上面的方法会改表输入的日期值
		long nDay = (basicDate.getTime() / (24 * 60 * 60 * 1000) + 1 + n) * (24 * 60 * 60 * 1000);
		Date date = new Date();
		date.setTime(nDay);
		return date2Str(date, DEFAULT_DATE_FORMAT);
	}

	/**
	 * 
	 * @param basicDate
	 *            8位的日期
	 * @param n
	 * @return 给定一个日期，返回加减n天后的日期 (n为负时，返回n天前的日期)
	 */
	public static String nDaysAfterOneDateStr(String basicDateStr, int n) {
		Date date = str2Date(basicDateStr, DEFAULT_DATE_FORMAT);
		return nDaysAfterOneDateStr(date, n);
	}

	/**
	 * 
	 * List<String>
	 * 
	 * @param stadat
	 *            开始日期 8位
	 * @param enddat
	 *            结束日期 8位
	 * @return 返回开始日期-结束日期之间的每一天(包括开始/结束日期)8位
	 */
	public static List<String> getAllDaysBetween(String stadat, String enddat) {
		Date sta = str2Date(stadat, DEFAULT_DATE_FORMAT);
		Date end = str2Date(enddat, DEFAULT_DATE_FORMAT);
		int interval = intervalDays(sta, end);// 相隔天数
		List<String> dayList = new ArrayList<String>(interval + 1);
		for (int i = 0; i < interval + 1; i++) {
			String nextNday = nDaysAfterOneDateStr(sta, i);
			dayList.add(nextNday);
		}
		return dayList;
	}

	public static String curTimeToOracleTimesamp() {
		return toOracleTimesamp(getCutTime());
	}

	public static String toOracleTimesamp(Timestamp time) {

		return "to_timestamp('" + time + "','yyyy-mm-dd hh24:mi:ss.ff') ";
	}

	/**
	 * 
	 * String
	 * 
	 * @param dtStr
	 * @param format
	 * @return 根据日前计算星期 返回{"日", "一", "二", "三", "四", "五", "六"};
	 */
	public static String getWeekOfDate(String dtStr, String format) {
		Calendar cal = Calendar.getInstance();
		Date date = str2Date(dtStr, format);
		return getWeekOfDate(date);
	}

	/**
	 * 
	 * String
	 * 
	 * @param dtStr
	 * @param format
	 * @return 根据8位日前计算星期返回{"日", "一", "二", "三", "四", "五", "六"};
	 */
	public static String getWeekOfDate(String dtStr) {
		return getWeekOfDate(dtStr, "yyyyMMdd");
	}

	/**
	 * 
	 * String
	 * 
	 * @param dtStr
	 * @param format
	 * @return 根据日期计算星期返回{"日", "一", "二", "三", "四", "五", "六"};
	 */
	public static String getWeekOfDate(Date dt) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(dt);
		int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
		if (w < 0)
			w = 0;
		return WEEK_DAYS[w];
	}

	/**
	 * 
	 * 
	 * @param yearMonth
	 *            格式yyyyMM
	 * @return 给定月份计算该月的天
	 */
	public static List<String> getMonthDays(String yearMonth) {
		String year = yearMonth.substring(0, 4);
		String month = yearMonth.substring(4, 6);
		SimpleDateFormat format = new SimpleDateFormat("yyyyMM");
		Date date = null;
		try {
			date = format.parse(yearMonth);
			Calendar calendar = Calendar.getInstance();
			calendar.setTime(date);
			int countDays = calendar.getActualMaximum(Calendar.DAY_OF_MONTH); // 该月共有多少天
			List<String> ret = new ArrayList<String>(countDays);
			for (int i = 1; i <= countDays; i++) {
				if (i < 10) {
					ret.add(yearMonth + "0" + i);
				} else {
					ret.add(yearMonth + i);
				}
			}
			return ret;
		} catch (ParseException e) {
		}
		return null;
	}

	/**
	 * 
	 * String
	 * 
	 * @return 获得当前时间的小时分钟，返回格式HH:mm
	 */
	public static String getCurHoursMinutes() {
		Timestamp time = new Timestamp(System.currentTimeMillis());
		return time.getHours() + ":" + time.getMinutes();
	}

	/**
	 * 
	 * List<String>
	 * 
	 * @param year
	 * @return 获取一年中的所有周末
	 */
	public static List<String> getWeekendByYear(String yearStr) {
		int year = Integer.parseInt(yearStr);
		SimpleDateFormat df = new SimpleDateFormat("yyyymmdd");
		Calendar calendar = new GregorianCalendar(year, 0, 1);
		int i = 1;
		List<String> retList = new ArrayList<String>();
		while (calendar.get(Calendar.YEAR) < year + 1) {
			calendar.set(Calendar.WEEK_OF_YEAR, i++);
			calendar.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
			if (calendar.get(Calendar.YEAR) == year) {// 星期天
				String date = date2Str(calendar.getTime(), DEFAULT_DATE_FORMAT);
				retList.add(date);
			}
			calendar.set(Calendar.DAY_OF_WEEK, Calendar.SATURDAY);
			if (calendar.get(Calendar.YEAR) == year) {// 星期六
				String date = date2Str(calendar.getTime(), DEFAULT_DATE_FORMAT);
				retList.add(date);
			}
		}
		return retList;
	}

	public static int getSubtractMin(Date nowHoursMinutes, Date formeHoursMinutes) {
		long startT = nowHoursMinutes.getTime();
		long endT = formeHoursMinutes.getTime();
		long ss = (startT - endT) / (1000);
		int MM = (int) ss / 60; // 共计分钟数
		// int hh=(int)ss/3600; //共计小时数
		// int dd=(int)hh/24; //共计天数
		return MM;
	}

	/**
	 * 
	 * @author Wonpera
	 * @data 2013-3-25
	 * @Title getNowOfLastMonth
	 * @param yearMonth
	 * @return
	 * @Description 得到一个月的上个月
	 */
	public static String getNowOfLastMonth(String yearMonth) {
		String year = yearMonth.substring(0, 4);
		String month = yearMonth.substring(4, 6);
		SimpleDateFormat format = new SimpleDateFormat("yyyyMM");
		Calendar calendar = Calendar.getInstance();
		Date date = null;
		try {
			date = format.parse(yearMonth);
			calendar.setTime(date);
			calendar.set(Calendar.DAY_OF_MONTH, 1);
			calendar.add(Calendar.DAY_OF_MONTH, -1);
			String lastMonth = date2Str(calendar.getTime(), DEFAULT_DATE_FORMAT);
			return (String) lastMonth.subSequence(0, 6);
		} catch (Exception e) {

		}
		return null;
		// // Date Format will be display
		// SimpleDateFormat aSimpleDateFormat = new SimpleDateFormat("yyyyMM");
		// GregorianCalendar aGregorianCalendar = new GregorianCalendar();
		// // Get last month GregorianCalendar object
		// aGregorianCalendar.set(Calendar.MONTH, aGregorianCalendar
		// .get(Calendar.MONTH) - 1);
		// // Format the date to get year and month
		// String nowOfLastMonth = aSimpleDateFormat
		// .format(aGregorianCalendar.getTime());
		// return nowOfLastMonth;
	}

	public static Date getMonday() {
		Calendar cal = Calendar.getInstance();
		cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY); // 获取本周一的日期
		/*
		 * //这种输出的是上个星期周日的日期，因为老外那边把周日当成第一天 cal.set(Calendar.DAY_OF_WEEK,
		 * Calendar.SUNDAY); //增加一个星期，才是我们中国人理解的本周日的日期
		 * cal.add(Calendar.WEEK_OF_YEAR, 1);
		 */
		// 设置时分秒
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		cal.set(Calendar.MILLISECOND, 0);
		return cal.getTime();
	}

	public static Date getSunday() {
		Calendar cal = Calendar.getInstance();
		cal.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
		// 增加一个星期，才是我们中国人理解的本周日的日期
		cal.add(Calendar.WEEK_OF_YEAR, 1);
		// 设置时分秒
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		cal.set(Calendar.MILLISECOND, 0);
		return cal.getTime();
	}

	public static Date getMonthFirst() {

		// 获取当前月第一天：
		Calendar c = Calendar.getInstance();
		c.add(Calendar.MONTH, 0);
		c.set(Calendar.DAY_OF_MONTH, 1);// 设置为1号,当前日期既为本月第一天
		return c.getTime();
	}

	public static Date getMonthLast() {
		// 获取当前月最后一天
		Calendar ca = Calendar.getInstance();
		ca.set(Calendar.DAY_OF_MONTH, ca.getActualMaximum(Calendar.DAY_OF_MONTH));
		return ca.getTime();
	}

	/**
	 *
	 * @param yearMonth
	 * @param year
	 * @return
	 */
	public static String getMonthByAdd(String yearMonth, int year) {
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		Calendar calendar = Calendar.getInstance();
		Date date = null;
		try {
			date = format.parse(yearMonth);
			calendar.setTime(date);
			// calendar.set(2015,15,29);
			calendar.add(Calendar.MONTH, year);

			String lastMonth = DateUtil.date2Str(calendar.getTime(), DEFAULT_DATE_FORMAT);
			System.out.println(lastMonth);
			return (String) lastMonth.subSequence(0, 10);
		} catch (Exception e) {

		}
		return null;
	}

	/**
	 * 获取两个日期之间相差年份
	 * 
	 * @param start
	 *            起始日期
	 * @param end
	 *            结束日期
	 * @return
	 */
	public static int getYearsBetween(Date start, Date end) {
		int year = 0;
		if (null != start && null != end) {
			Calendar cStart = Calendar.getInstance();
			Calendar cEnd = Calendar.getInstance();
			cStart.setTime(start);
			cEnd.setTime(end);
			year = cEnd.get(Calendar.YEAR) - cStart.get(Calendar.YEAR);
			// 如果是年龄，这样计算的是周岁
			// if (cEnd.get(Calendar.DAY_OF_YEAR) <
			// cStart.get(Calendar.DAY_OF_YEAR)) {
			// year--;
			// }
		}
		return year;
	}

	/**
	 * 前一个小时
	 */
	public static Date beforeOneHourToNowDate() {
		Calendar calendar = Calendar.getInstance();

		/* HOUR_OF_DAY 指示一天中的小时 */
		calendar.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY) - 1);

		return calendar.getTime();
	}

	/**
	 * 前二个小时
	 */
	public static Date beforeTwoHourToNowDate() {
		Calendar calendar = Calendar.getInstance();

		/* HOUR_OF_DAY 指示一天中的小时 */
		calendar.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY) - 2);

		return calendar.getTime();
	}

	/**
	 * 前三个小时
	 */
	public static Date beforeThrToNowDate() {
		Calendar calendar = Calendar.getInstance();

		/* HOUR_OF_DAY 指示一天中的小时 */
		calendar.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY) - 3);

		return calendar.getTime();
	}
	
	/**
	 * 前四个小时
	 */
	public static Date beforeFourHourToNowDate() {
		Calendar calendar = Calendar.getInstance();

		/* HOUR_OF_DAY 指示一天中的小时 */
		calendar.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY) - 4);

		return calendar.getTime();
	}

	/**
	 * 后一个小时
	 */
	public static Date afterOneHourToNowDate() {
		Calendar calendar = Calendar.getInstance();

		/* HOUR_OF_DAY 指示一天中的小时 */
		calendar.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY) + 1);

		return calendar.getTime();
	}

	/**
	 * 前一天
	 */
	public static Date beforeOneDayToNowDate() {
		Calendar calendar = Calendar.getInstance();

		/* HOUR_OF_DAY 指示一天中的小时 */
		calendar.set(Calendar.HOUR_OF_DAY - 1, calendar.get(Calendar.HOUR_OF_DAY));

		return calendar.getTime();
	}

	/**
	 * 前一天
	 */
	public static Date beforeOneDay() {
		Calendar calendar = Calendar.getInstance();

		/* HOUR_OF_DAY 指示一天中的小时 */
		calendar.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY) - 24);

		return calendar.getTime();
	}

	/**
	 * 前一周
	 */
	public static Date beforeOneWeek() {
		Calendar calendar = Calendar.getInstance();

		/* HOUR_OF_DAY 指示一天中的小时 */
		calendar.set(Calendar.DAY_OF_MONTH, calendar.get(Calendar.DAY_OF_MONTH) - 7);

		return calendar.getTime();
	}
	
	/**
	 * 前一周
	 */
	public static String OneWeekStr() {
		Calendar calendar = Calendar.getInstance();

		/* HOUR_OF_DAY 指示一天中的小时 */
		calendar.set(Calendar.DAY_OF_MONTH, calendar.get(Calendar.DAY_OF_MONTH) - 7);

		SimpleDateFormat sdf = new SimpleDateFormat(DEFAULT_DATE_FORMAT);
		return sdf.format(calendar.getTime());
	}


	public static void main(String[] args) {
		System.out.println(beforeOneWeek());
		System.out.println(getCurrentDate());
		System.out.println(intervalDays(beforeOneWeek(),new Date()));
	}
}